package com.edfu.core.coursemgt.persistence.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.edfu.core.coursemgt.persistence.api.ICourseMgtPersistence;
import com.edfu.core.coursemgt.persistence.entity.AcadSemCourseBranchRelnEntity;
import com.edfu.core.coursemgt.persistence.entity.CourseCourseOfferingRelnEntity;
import com.edfu.core.coursemgt.persistence.entity.CourseEntity;
import com.edfu.core.coursemgt.persistence.entity.CourseOfferingEntity;
import com.edfu.core.coursemgt.persistence.entity.CourseOfferingInstanceEntity;
import com.edfu.core.coursemgt.persistence.entity.ICourseMgtEntity;
import com.edfu.core.coursemgt.persistence.entity.LessonEntity;
import com.edfu.core.coursemgt.persistence.entity.LessonUnitEntity;
import com.edfu.core.identitymgt.persistence.entity.UserEnrollmentEntity;
import com.edfu.core.institutemgt.persistence.entity.AcadSemBatchRelnEntity;
import com.edfu.core.institutemgt.persistence.entity.AcadSemBranchRelnEntity;
import com.edfu.core.institutemgt.persistence.entity.BatchEntity;

@Transactional
@Repository
public class CourseMgtPersistenceImpl implements ICourseMgtPersistence {
	
	private EntityManager entityManager;
	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
	
	@Override
	public CourseEntity getCourse(String courseCode) {
		Query q = entityManager.createQuery("select c from CourseEntity c where c.code = :courseCode ");
		q.setParameter("courseCode", courseCode);
		CourseEntity ce = (CourseEntity)q.getSingleResult();
		return ce;
	}
	
	@Override
	public CourseEntity getCourse(long courseId) {
		return entityManager.find(CourseEntity.class, courseId);
	}
	
	@Override
	public AcadSemBranchRelnEntity getAcadSemBranchReln(String branchCode, String semCode) {
		Query q = entityManager.createQuery("select asb from AcadSemBranchRelnEntity asb where asb.branch.code = :branchCode and asb.semester.code = :semCode ");
		q.setParameter("branchCode", branchCode);
		q.setParameter("semCode", semCode);		
		AcadSemBranchRelnEntity asbre = (AcadSemBranchRelnEntity)q.getSingleResult();
		return asbre;
	}
	
	@Override
	public List<AcadSemCourseBranchRelnEntity> getCoursesToBeTaughtInAnySem(String branchCode) {
		Query q = entityManager.createQuery("select asb from AcadSemCourseBranchRelnEntity ascb where ascb.semInBranch.branch.code = :branchCode ");
		q.setParameter("branchCode", branchCode);	
		@SuppressWarnings("unchecked")
		List<AcadSemCourseBranchRelnEntity> resultList =(List<AcadSemCourseBranchRelnEntity>)q.getResultList();
		return resultList;
	}
	
	@Override
	public List<AcadSemCourseBranchRelnEntity> getCoursesToBeTaughtInGivenSem(String branchCode, String semesterCode) {
		Query q = entityManager.createQuery("select ascb from AcadSemCourseBranchRelnEntity ascb where ascb.semInBranch.branch.code = :branchCode and ascb.semInBranch.semester.code =:semesterCode");
		q.setParameter("branchCode", branchCode);	
		q.setParameter("semesterCode", semesterCode);
		@SuppressWarnings("unchecked")
		List<AcadSemCourseBranchRelnEntity> resultList =(List<AcadSemCourseBranchRelnEntity>)q.getResultList();
		return resultList;
	}
	
	@Override
	public List<CourseCourseOfferingRelnEntity> getAssociatedCoursesForOffering(String courseOfferingCode) {
		Query q = entityManager.createQuery("select ccor from CourseCourseOfferingRelnEntity ccor where ccor.courseOffering.code = :courseOfferingCode ");
		q.setParameter("courseOfferingCode", courseOfferingCode);	
		@SuppressWarnings("unchecked")
		List<CourseCourseOfferingRelnEntity> resultList =(List<CourseCourseOfferingRelnEntity>)q.getResultList();
		return resultList;
	}
	
	@Override
	public AcadSemBatchRelnEntity getActiveSemesterForBatch(BatchEntity be) {
		Query q = entityManager.createQuery("select e from AcadSemBatchRelnEntity e where e.batch.code = :batchCode and e.status='ACTIVE'");
		q.setParameter("userId", be.getCode());
		return (AcadSemBatchRelnEntity)q.getResultList().get(0);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<UserEnrollmentEntity> getUserEnrollments(String userId, String userRole) {
		List<UserEnrollmentEntity> enrollmentsList = null;
		Query q = entityManager.createQuery("select e from UserEnrollmentEntity e where e.user.userId = :userId and e.role.name = :userRole");
		q.setParameter("userId", userId);
		q.setParameter("userRole", userRole);
		enrollmentsList = q.getResultList();
		return enrollmentsList;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<AcadSemCourseBranchRelnEntity> getCoursesInSemForBranch(String semesterCode, String branchCode) {
		List<AcadSemCourseBranchRelnEntity> coursesInSem = null;
		Query q = entityManager.createQuery("select e from AcadSemCourseBranchRelnEntity e where e.semInBranch.semester.code = :semesterCode and and e.semInBranch.branch.code = :branchCode");
		q.setParameter("branchCode", branchCode);
		q.setParameter("semesterCode", semesterCode);
		coursesInSem = q.getResultList();
		return coursesInSem;
	}


	@Override
	public void persist(ICourseMgtEntity entity) {
		entityManager.persist(entity);
	}
	
	@Override
	public CourseEntity merge(CourseEntity entity) {
		return entityManager.merge(entity);
	}

	@Override
	public AcadSemCourseBranchRelnEntity getCourseIfTaughtInSem(String courseCode, String branchCode,
			String semesterCode) {
		AcadSemCourseBranchRelnEntity ce = null ;
		Query q = entityManager.createQuery("select e from AcadSemCourseBranchRelnEntity e where e.semInBranch.semester.code = :semesterCode and e.semInBranch.branch.code = :branchCode " +
				"and e.course.code=:courseCode");
		q.setParameter("branchCode", branchCode);
		q.setParameter("semesterCode", semesterCode);
		q.setParameter("courseCode", courseCode);
		List<?> resultList = q.getResultList();
		if ( resultList == null || resultList.size() == 0)
			return null;
		ce = (AcadSemCourseBranchRelnEntity)q.getResultList().get(0);
		return ce;
	}
	
	@Override
	public boolean teaches(String teacherUserId, String courseCode, String branchCode, String semesterCode) {
		Query q = entityManager.createQuery("select e from AcadSemCourseBranchUserRelnEntity e where e.courseInGivenSemInBranch.semInBranch.semester.code = :semesterCode " +
				"and e.courseInGivenSemInBranch.semInBranch.branch.code = :branchCode and e.courseInGivenSemInBranch.course.code=:courseCode and e.userEnrollment.user.userId = :teacherUserId");
		q.setParameter("branchCode", branchCode);
		q.setParameter("semesterCode", semesterCode);
		q.setParameter("courseCode", courseCode);
		q.setParameter("teacherUserId", teacherUserId);
		List<?> resultList = q.getResultList();
		if (resultList != null && resultList.size() > 0)
			return true;
		else
			return false;
	}


	@Override
	public List<CourseOfferingEntity> getAllCourseOfferingsForBranchByMe(
			String userId, String branchCode) {
		// TODO Auto-generated method stub
		return null;
	}


	@SuppressWarnings("unchecked")
	@Override
	public List<CourseOfferingInstanceEntity> getCourseOfferingInstancesCurrentlyTaughtByMe(
			String userId) {
		Query q = entityManager.createQuery("select e from CourseOfferingInstanceEntity e where e.owner.userId = :userId and e.status='Active'");
		q.setParameter("userId", userId);
		return q.getResultList();
	}


	@Override
	public List<CourseOfferingInstanceEntity> getCourseOfferingInstancesAuthoredByMe(
			String userId) {
		// TODO Auto-generated method stub
		return null;
	}
	

	@SuppressWarnings("unchecked")
	@Override
	public List<CourseOfferingInstanceEntity> getCourseOfferingInstancesCurrentlyTaughtToMe(
			String userId) {
		Query q = entityManager.createQuery("select ce from CourseOfferingInstanceEntity ce, BatchEntity be, SectionEntity se, in (se.members) as l  where ce.status='Active' and l.userEnrollment.user.userId =:userId and ce.batch.id = be.id and be.id = se.batch.id");
		q.setParameter("userId", userId);
		return q.getResultList();
	}

	@Override
	public void remove(ICourseMgtEntity entity) {
		// TODO Auto-generated method stub
		
	}





}
